﻿using Core.Framework.Model.Common;
using Core.Framework.Model.WebSockets;
using Core.Framework.Redis;
using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Core.Framework.Util.Common;
using Core.IBusiness.ILoggerModule;
using Core.Middleware.WebSockets.TimerJobs;
using Core.Service.TaskHandle;
using Microsoft.AspNetCore.Builder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Core.Middleware.WebSockets
{
    public static class UseWebSocketConfig 
    {

        /// <summary>
        /// ws 中间键
        /// </summary>
        /// <typeparam name="TWebSocket">WebSocket工厂</typeparam>
        /// <typeparam name="WebSocketMessage">WebSocket消息工厂</typeparam>
        /// <param name="applicationBuilder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseWebSocketsMiddleware(this IApplicationBuilder applicationBuilder )
        {
            // WS 参数配置
            applicationBuilder.UseWebSockets(new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(6)
            });

            // 初始化消息监听器
            TaskHandleFactory.Initialization(true);

            // 如果未Null 结束操作
            if (TaskHandleFactory
                    .MQMsgHandlers.Count() == 0)
                new Exception($"使用 'UseWebSocketsMiddleware' 需要注册:MQMsgHandlers");

            // 初始化订阅列表
            foreach (var item in TaskHandleFactory.MQMsgHandlers)
            {
                WebSocketApplication.TempSubscriptions.TryAdd(item.Template.ToLower(), new List<string>());
            }

            return applicationBuilder.UseMiddleware<WebSocketMidWare>();
        }

        /// <summary>
        /// 队列处理
        /// [QueueTimedLoop]
        /// </summary>
        /// <param name="applicationBuilder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseQueueLoop(this IApplicationBuilder applicationBuilder)
        {
            // 获取日志服务
            ILog iLog = BuildServiceProvider.GetService<ILog>();

            // redis 链接预热
            var preloading = RedisConnectionHelper.Instance;

            // 实例redis
            var redis = new RedisHelper();

            // 注册当前客户机服务[集群]
            {
                // 初始化消息监听器
                TaskHandleFactory.Initialization(true);

                // 如果未Null 结束操作
                if (TaskHandleFactory.MQMsgHandlers.Count == 0)
                    return applicationBuilder;

                var temps = new List<Listener_Template>();

                // 初始化服务集合
                foreach (var handler in TaskHandleFactory.MQMsgHandlers)
                    temps.Add(new Listener_Template {template = handler.Template, Subscription = null});

                redis.HashSet(
                    RedisQueueHelperParameter.QueueService,
                    RedisQueueHelperParameter.ServiceClinet,
                    new QueueService
                    {
                        Title = CoreStartupHelper.GetConfigValue("Service:Title"),
                        ApiUrl = CoreStartupHelper.GetConfigValue("Service:Url"),
                        Temps = temps,
                        System = CoreStartupHelper.GetConfigValue("Service:System"),
                        EndRefreshTime = DateTime.Now
                    });

                // 订阅当前服务客户机
                redis.Subscribe(RedisQueueHelperParameter.ServiceClinet, (channle, msg) =>
                {

                    var msgModel = msg.ToString().TryToEntity<MessageQueue>();

                    iLog.Queue<QueueService>(new
                    {
                        Client = CoreStartupHelper.GetConfigValue("Service:Title")
                    }.TryToJson(), "subscribe", msgModel.ClientInfo.Project.ProjectToken, msgModel.Message.Token);

                    RedisQueueHelper.SortedPush(RedisQueueHelperParameter.Queue, msg);
                });
            }

            // 实例数量
            var length = CoreStartupHelper.GetConfigValue("QueueTimedLoop:length").ToInt(1);

            // 休眠时间/s
            var sleeps = CoreStartupHelper.GetConfigValue("QueueTimedLoop:parameter:sleep").ToInt(1);

            // 并发线程数
            var threadLength =  CoreStartupHelper.GetConfigValue("QueueTimedLoop:parameter:threadLength").ToInt(10);


            var job = new TimerJob();

            // 注册服务
            while (length > 0)
            {
                Thread.Sleep((sleeps * 1000) / length);
                length--;


                job.RegisterDisallowConcurrent<ExecQueueTask>(a => 
                    a.WithIntervalInSeconds(sleeps).RepeatForever(),
                    a =>
                    {
                        a.Put("threadLength", threadLength);
                    });

            }

            return applicationBuilder;
        }

        /// <summary>
        /// 卸载[WebSocket]服务[Client]
        /// </summary>
        /// <param name="applicationBuilder"></param>
        /// <returns></returns>
        public static IApplicationBuilder UninstallWebSocketServiceClient(this IApplicationBuilder applicationBuilder)
        {
            // 实例redis
            var redis = new RedisHelper();
            redis.HashDelete(RedisQueueHelperParameter.QueueService, RedisQueueHelperParameter.ServiceClinet);
            return applicationBuilder;
        }

        /// <summary>
        /// 消息备份
        /// 1. 离线消息
        /// 2. 在线消息
        /// </summary>
        /// <param name="sleep">默认一分半钟检查备份一次</param>
        /// <returns></returns>
        public static IApplicationBuilder UseQueueMsgBackups(this IApplicationBuilder applicationBuilder, int sleepSeconds = 90)
        {

            var job = new TimerJob();

            job.Register<MsgBackups>(a => a.WithIntervalInSeconds(sleepSeconds).RepeatForever());

            return applicationBuilder;
        }

    }
}
